package com.jk.vehicle.core.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.jk.vehicle.core.exception.CustomExceptionResolver;
import com.jk.vehicle.core.filter.CustomJsonValueFilter;
import com.jk.vehicle.core.filter.LocaleFilter;
import com.jk.vehicle.core.filter.XssFilter;
import com.jk.vehicle.core.listener.ApplicationReadyListener;
import com.jk.vehicle.core.utils.InstanceUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.Charset;
import java.util.List;

/**
 * 江河 Spring MVC 默认配置
 *
 * @author KangJian
 * @date 2018/7/18
 */
@Configuration
public class JhWebMvcConfigurer extends WebMvcConfigurationSupport {
	/**
	 * 默认环境变量
	 */
	private static final String DEV_ENV = "dev";
	/**
	 * 当前激活的配置文件
	 */
	@Value("${spring.profiles.active}")
	private String env;

	/**
	 * 统一异常处理
	 *
	 * @param exceptionResolvers
	 */
	@Override
	public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
		exceptionResolvers.add(new CustomExceptionResolver());
	}

	/**
	 * 解决跨域问题
	 *
	 * @param registry
	 */
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**");
	}

	/**
	 * 应用状态监听器
	 * @return
	 */
	@Bean
	public ApplicationReadyListener applicationReadyListener() {
		return new ApplicationReadyListener();
	}

	/**
	 * 字符编码过滤器
	 * @return
	 */
	//	@Bean
	//	public FilterRegistrationBean<CharacterEncodingFilter> encodingFilterRegistration() {
	//		CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
	//		encodingFilter.setEncoding("UTF-8");
	//		encodingFilter.setForceEncoding(true);
	//		FilterRegistrationBean<CharacterEncodingFilter> registration = new FilterRegistrationBean<CharacterEncodingFilter>(
	//				encodingFilter);
	//		registration.setName("encodingFilter");
	//		registration.addUrlPatterns("/*");
	//		registration.setAsyncSupported(true);
	//		registration.setOrder(1);
	//		return registration;
	//	}

	/**
	 * 本地化过滤器
	 * @return
	 */
	@Bean
	public FilterRegistrationBean<LocaleFilter> localeFilterRegistration() {
		FilterRegistrationBean<LocaleFilter> registration = new FilterRegistrationBean<LocaleFilter>(
				new LocaleFilter());
		registration.setName("localeFilter");
		registration.addUrlPatterns("/*");
		registration.setOrder(2);
		return registration;
	}

//	/**
//	 * csrf过滤器
//	 * @return
//	 */
//	@Bean
//	public FilterRegistrationBean<CsrfFilter> csrfFilterRegistration() {
//		FilterRegistrationBean<CsrfFilter> registration = new FilterRegistrationBean<CsrfFilter>(new CsrfFilter());
//		registration.setName("csrfFilter");
//		registration.addUrlPatterns("/*");
//		registration.setOrder(3);
//		return registration;
//	}

	/**
	 * xss过滤器
	 * @return
	 */
	@Bean
	public FilterRegistrationBean<XssFilter> xssFilterRegistration() {
		FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<XssFilter>(new XssFilter());
		registration.setName("xssFilter");
		registration.addUrlPatterns("/*");
		registration.setOrder(4);
		return registration;
	}

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	@Override
	public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
		FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
		List<MediaType> mediaTypes = InstanceUtil.newArrayList();
		mediaTypes.add(MediaType.valueOf("application/json;charset=UTF-8"));
		mediaTypes.add(MediaType.valueOf("multipart/form-data"));
		converter.setSupportedMediaTypes(mediaTypes);
		FastJsonConfig config = new FastJsonConfig();
		// 保留空的字段,引号字段名 s
		config.setSerializerFeatures(SerializerFeature.WriteMapNullValue, SerializerFeature.QuoteFieldNames,
				SerializerFeature.DisableCircularReferenceDetect);
		// xss过滤
		config.setSerializeFilters(new CustomJsonValueFilter());
		converter.setFastJsonConfig(config);
		converter.setDefaultCharset(Charset.forName("UTF-8"));
		converters.add(0, converter);
		converters.add(new ByteArrayHttpMessageConverter());
	}

	/**
	 * 文件上传配置
	 */
	/**
	@Bean
	public MultipartConfigElement multipartConfigElement() {
		MultipartConfigFactory factory = new MultipartConfigFactory();
		// 文件最大 KB,MB
		factory.setMaxFileSize("100MB");
		/// 设置总上传数据总大小
		factory.setMaxRequestSize("100MB");
		return factory.createMultipartConfig();
	}
	**/

	/**
	 * 资源重定向(仅作为后台使用不提供静态资源)
	 *
	 * @param registry
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		//第一个方法设置访问路径前缀，第二个方法设置资源路径
		registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
		registry.addResourceHandler("/**").addResourceLocations("classpath:/views/");
		registry.addResourceHandler("upload/**").addResourceLocations("/WEB-INF/upload/");
		registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
	}

}